package controlador;

import java.util.ArrayList;
import java.util.Collection;

import javax.swing.DefaultListModel;

import persistencia.AdministradorPersistenciaFactura;
import persistencia.AdministradorPersistenciaMaterial;
import persistencia.AdministradorPersistenciaOrdenDeCompra;
import persistencia.AdministradorPersistenciaProducto;
import persistencia.AdministradorPersistenciaProveedor;
import model.ConTemporada;
import model.Conjunto;
import model.Factura;
import model.Material;
import model.MaterialView;
import model.OrdenDeCompra;
import model.Prenda;
import model.Producto;
import model.Proveedor;
import model.SinTemporada;


public class Controlador {
	private Collection<Proveedor> proveedores;
	private Collection<OrdenDeCompra> ordenesCompra;
	private Collection<Producto> productos;
	private Collection<Factura> facturas;
	private Collection<Material> materiales;
	private static Controlador instancia;
	
	private Controlador(){
		
		proveedores = new ArrayList<Proveedor>();
		ordenesCompra = new ArrayList<OrdenDeCompra>();
		productos = new ArrayList<Producto>();
		facturas = new ArrayList<Factura>();
		materiales = new ArrayList<Material>();
	}
	
	/* SINGLETON CONTROLADOR */
	
	public static Controlador getInstancia(){
		if(instancia == null){
			instancia = new Controlador();
		}
		
		return instancia;
	}
	

	/* BUSCAR PRODUCTO */
	
	private Producto buscarProducto(int codigo) {
		Producto prod = null;
		for(Producto producto : productos){
			if(producto.sosElProducto(codigo)){
				prod = producto;
			}
			
		}
		if(prod == null){
			prod = AdministradorPersistenciaProducto.getInstancia().selectProducto(codigo);
			if(prod!=null){
				productos.add(prod);
			}
		}
		
		return prod;
	}
	

	/* BUSCAR MATERIAL */
	
	private Material buscarMaterial(int codigo) {
		
		Material mat = null;
		for(Material material : materiales){
			if(material.sosElMaterial(codigo)){
				mat = material;
			}
		}
		if(mat == null){
			mat = AdministradorPersistenciaMaterial.getInstancia().selectMaterial(codigo);
			if(mat!=null){
				materiales.add(mat);
			}
		}
	
		return mat;
	}
	
		
	/* ALTA DE MATERIAL */
	
	public void altaMaterial(int codigo, String nombre, float stock, float puntoPedido,
			float stockMaximo, float costo, int cuitProv) throws Exception{
		Material material = buscarMaterial(codigo);
		
		if(material == null){
			Proveedor proveedor = buscarProveedor(cuitProv);
			if(proveedor != null){
			
		
				Material m = new Material(codigo, nombre, stock, puntoPedido, stockMaximo, costo);
				materiales.add(m);
				proveedor.addMaterial(m);
				AdministradorPersistenciaMaterial.getInstancia().insert(m, proveedor);
			}
			else{
				throw new Exception("No se encuentra proveedor");
			}
		}
		
	}
	
	/*TRAER TODOS LOS VIEW DE LOS MATERIALES */
	
	public DefaultListModel<String> getMaterialesView(){
		DefaultListModel<String> materialesView = new DefaultListModel<String>();
		ArrayList<Material> materiales = AdministradorPersistenciaMaterial.getInstancia().selectMateriales();
		for(Material material:materiales){
			materialesView.addElement(material.getView().getString());
		}
		return materialesView;
	}
	
		
	/*ALTA PRENDA TEMPORADA */
	
	public void altaPrendaTemporada(int codigo, String nombre, int stock, String temporada) {
		Producto producto = buscarProducto(codigo);
		if(producto == null){
			ConTemporada prod = new ConTemporada(codigo, nombre, stock, temporada);
			AdministradorPersistenciaProducto.getInstancia().insertProductoTemporada(prod);
			productos.add(prod);
			}
		
		}
	
	
	/* ASIGNAR MATERIAL A PRENDA */
	
	public void ingresarMaterial(int codProducto, int codMaterial, float cantidad){
		Producto prod = buscarProducto(codProducto);
		if(prod != null){
			Material material = buscarMaterial(codMaterial);
			if(material != null){
				((Prenda)prod).crearItemMaterial(material, cantidad);
				AdministradorPersistenciaProducto.getInstancia().insertItemMaterial(prod.getCodigo(),material.getCodigo(), cantidad);
			}
		}
	}
	
	/*ALTA PRENDA SIN TEMPORADA */
	
	public void altaPrendaSinTemporada(int codigo, String nombre, int stock) {
		Producto producto = buscarProducto(codigo);
		if(producto == null){
			SinTemporada prod = new SinTemporada(codigo, nombre, stock);
			AdministradorPersistenciaProducto.getInstancia().insertProductoSinTemporada(prod);
			productos.add(prod);
			}
		
		}
	
	public void agregarMaterialAPrenda(int codigoPrenda,int codigoMaterial, float cantidad ){
		
		Prenda p = (Prenda) buscarProducto(codigoPrenda);
		
		Material material = buscarMaterial(codigoMaterial);
		
		p.crearItemMaterial(material, cantidad);
	}
	
	/*ALTA CONJUNTO */
	
	public void altaConjunto(int codigo, String nombre, float descuento){
		Producto producto = buscarProducto(codigo);
		Conjunto conj = null;
		if(producto == null){
			conj = new Conjunto(codigo, nombre, descuento);
			AdministradorPersistenciaProducto.getInstancia().insertConjunto(codigo, nombre, descuento);
			productos.add(conj);
		}
	}
	
	/* ASIGNAR PRODUCTO A CONJUNTO */
	
	public void ingresarProductoAConjunto(int codigoConjunto, int codigoProducto){
		Producto conjunto = buscarProducto(codigoConjunto);
		if(conjunto != null){
			Producto producto = buscarProducto(codigoProducto);
			if(producto != null){
				
				((Conjunto)conjunto).agregarProductoAConjunto(producto);
			}
		}
	}
	
	/* OBTENER PRECIO DE UN PRODUCTO */
	
	public float getPrecio(int codigo){
		float total = 0;
		Producto producto = buscarProducto(codigo);
		if(producto != null){
			total = producto.getPrecio();
		}
		return total;
	}
	
	/* ELIMINAR PRODUCTO DE CONJUNTO */
	
	public void eliminarProductoDeConjunto(int codConjunto, int codProducto){
		Producto producto = null;
		Producto conjunto = buscarProducto(codConjunto);
		if(conjunto != null){
			producto = ((Conjunto)conjunto).buscarProductoEnConjunto(codProducto);
			if(producto != null){
				((Conjunto)conjunto).eliminarProductoDeConjunto(producto);
			}
		}
	}
	
	/* ALTA DE PROVEEDOR */
	
	public void altaProveedor(int cuit, String nombre, String direccion){
		Proveedor proveedor = buscarProveedor(cuit);
		if(proveedor == null){
			
			proveedor = new Proveedor(cuit, nombre, direccion);
			proveedores.add(proveedor);
			AdministradorPersistenciaProveedor.getInstancia().insertProveedor(proveedor);
		}
		
	}
	
	
	
	/* BUSCAR PROVEEDOR */
	
	private Proveedor buscarProveedor(int cuit) {
		Proveedor prov = null;
		for(Proveedor proveedor : proveedores){
			if(proveedor.sosElProveedor(cuit)){
				prov = proveedor;
				
			}
		}
		if(prov == null){
			prov = AdministradorPersistenciaProveedor.getInstancia().selectProveedor(cuit);
		}
		return prov;
	}
	
	/* BAJA DE PRODUCTO */
	
	public void bajaProducto(int codProducto){
		Producto producto = buscarProducto(codProducto);
		if(producto.sePuedeBorrar(codProducto)){
			producto.eliminarProducto(producto);
			productos.remove(producto);
		}else{
			System.out.println("El producto a borrar forma parte de un Conjunto");
		}
	}
	
	/* GENERAR ORDEN DE COMPRA */

	public void generarOrdenDeCompra(){
		Collection<Material> materiales = null;
		OrdenDeCompra oc = null;
		for(Proveedor proveedor : proveedores){
			materiales = proveedor.getMaterialesAReponer();
			if(materiales != null){
				
				oc = new OrdenDeCompra(proveedor);
				ordenesCompra.add(oc);
				AdministradorPersistenciaOrdenDeCompra.getInstancia().insertOC(oc, proveedor);
				for(Material m : materiales){
					float cantidad = 0;
					cantidad = (m.getStockMaximo() - m.getStock());
					
					oc.AgregarItem(m, cantidad);
					
				}
			}
			
		}
		

	}
	
	/* CREAR FACTURA */
	
	public int altaFactura(String cliente){
		Factura factura = new Factura(cliente);
		AdministradorPersistenciaFactura.getInstancia().insertFactura(factura.getNumero(), cliente);
		facturas.add(factura);
		return factura.getNumero();
	}
	
	/* CARGAR ITEMS FACTURA */
	
	public void cargarItemFactura(int numeroFactura, int codProducto, int cantidad){
		Factura factura = buscarFactura(numeroFactura);
		if(factura != null){
			Producto producto = buscarProducto(codProducto);
			if(producto != null){
				factura.agregarItem(producto, cantidad);
			}
		}
	}
	
	/* BUSCAR FACTURA */
	
	private Factura buscarFactura(int numeroFactura) {
		Factura fact = null;
		for(Factura factura : facturas){
			if(factura.sosLaFactura(numeroFactura)){
				fact = factura;
				
			}
			
		}
		if(fact == null){
			fact = AdministradorPersistenciaFactura.getInstancia().selectFactura(numeroFactura);
		}
		return fact;
	}

	/* CALCULAR TOTAL DE FACTURA */
	
	public float calcularTotalFactura(int numeroFactura){
		Factura factura = buscarFactura(numeroFactura);
		float total = 0;
		if(factura != null){
		total = factura.calcularTotal();
		}
		return total;
	}
	
	/* MODIFICAR PRENDA SIN TEMPORADA */
	
	public void modificarPrendaSinTemporada(int codigo, String nombre, int stock){
		Producto producto = buscarProducto(codigo);
		if(producto != null){
			((SinTemporada)producto).setNombre(nombre);
			((SinTemporada)producto).setStock(stock);
			AdministradorPersistenciaProducto.getInstancia().updateSinTemporada(codigo, nombre, stock);
			
		}
	}
	
	/* MODIFICAR PRENDA CON TEMPORADA */
	
	public void modificarPrendaConTemporada(int codigo, String nombre, int stock, String estacion){
		Producto producto = buscarProducto(codigo);
		if(producto != null){
			((ConTemporada)producto).setNombre(nombre);
			((ConTemporada)producto).setStock(stock);
			((ConTemporada)producto).setEstacion(estacion);
			AdministradorPersistenciaProducto.getInstancia().updateConTemporada(codigo, nombre, stock, estacion);
		}
	}
	
	/* MODIFICAR CONJUNTO */
	
	public void modificarConjunto(int codigo, String nombre, float descuento){
		Producto producto = buscarProducto(codigo);
		if(producto != null){
			((Conjunto)producto).setNombre(nombre);
			((Conjunto)producto).setDescuento(descuento);
			AdministradorPersistenciaProducto.getInstancia().updateConjunto(codigo, nombre, descuento);
		}
	}
	
	/* CARGAR PRENDA */
	
	public void cargarPrenda(int codigo, int cantidad){
		Producto producto = buscarProducto(codigo);
		if(producto != null){
			if(((Prenda)producto).verificarStockMateriales(cantidad)== true){
				float stockAnterior = ((Prenda)producto).getStock();
				((Prenda)producto).agregarStock(cantidad);
				AdministradorPersistenciaProducto.getInstancia().updateStock(codigo, stockAnterior + cantidad);
			}
		}
	}

}
